package com.mapforge.gui.tools;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JToggleButton;

import com.mapforge.gui.interfaces.MapToolGUIInterface;
import com.mapforge.listener.MapToolChangeEvent;
import com.mapforge.listener.MapToolChangeListener;
import com.mapforge.listener.TileMapCreationEvent;
import com.mapforge.map.tools.MapToolInterface;

/**
 * The {@link MapToolButton} class presents users with a GUI control for
 * {@link MapTool}.
 * 
 * @author Will Morrison
 * 
 */
public class MapToolButton extends JToggleButton implements
		MapToolGUIInterface {

	/**
	 * Default serial version ID, here to remove warnings.
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * The map editor tool control this button represents.
	 */
	private MapToolInterface mapTool;

	/**
	 * Special panel used to present user with additional controls specific to
	 * the map tool this button represents
	 */
	private JPanel mapToolPanel;

	private List<MapToolChangeListener> toolListeners;

	private Cursor cursor;

	/**
	 * Constructs a new button using the specified icon and map tool.
	 * 
	 * @param icon
	 *            this button's icon
	 * @param mapTool
	 *            editing tool this button represents
	 */
	public MapToolButton(ImageIcon icon, MapToolInterface mapTool,
			JPanel mapToolPanel) {
		super();
		this.mapToolPanel = mapToolPanel;
		this.setIcon(icon);
		this.setPreferredSize(new Dimension(icon.getIconWidth() + 8, icon
				.getIconHeight() + 8));
		this.mapTool = mapTool;
		this.setToolTipText(mapTool.getDescription());
		toolListeners = new ArrayList<MapToolChangeListener>();
		addActionListener(new ToolButtonListener());
		cursor = Cursor.getDefaultCursor();
	}

	public void addMapToolChangeListener(MapToolChangeListener listener) {
		this.toolListeners.add(listener);
	}

	public boolean removeMapToolChangeListener(MapToolChangeListener listener) {
		return this.toolListeners.remove(listener);
	}

	public void clearMapToolChangeListeners() {
		this.toolListeners.clear();
	}

	protected void fireMapToolChangeEvent(MapToolChangeEvent event) {
		for (MapToolChangeListener listener : toolListeners) {
			listener.mapToolChangePerformed(event);
		}
	}

	public void setMapToolPanel(JPanel panel) {
		this.mapToolPanel = panel;
	}

	public JPanel getMapToolPanel() {
		return mapToolPanel;
	}

	/**
	 * Returns the editing tool this button represents.
	 * 
	 * @return editing tool this button represents
	 */
	public MapToolInterface getMapTool() {
		return this.mapTool;
	}

	private class ToolButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent arg0) {
			fireMapToolChangeEvent(new MapToolChangeEvent(MapToolButton.this,
					mapTool));
		}

	}

	@Override
	public void setMapToolCursor(Cursor cursor) {
		this.cursor = cursor;
	}

	@Override
	public Cursor getMapToolCursor() {
		return cursor;
	}

	@Override
	public void tileMapCreationPerformed(TileMapCreationEvent mapCreationEvent) {
		mapTool.setTileMap(mapCreationEvent.getTileMapCreated());
	}
}
